package com.coolmusic;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.Image;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.mlkit.vision.barcode.Barcode;
import com.google.mlkit.vision.barcode.BarcodeScanner;
import com.google.mlkit.vision.barcode.BarcodeScannerOptions;
import com.google.mlkit.vision.barcode.BarcodeScanning;
import com.google.mlkit.vision.common.InputImage;

import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ScanActivity extends AppCompatActivity {

    private static final int REQUEST_CODE_CAMERA_PERMISSION = 100;
    private static final String[] PERMISSIONS = {Manifest.permission.CAMERA};

    private PreviewView previewView;
    private ImageView scanLine;
    private TextView hintText;
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
    private ExecutorService cameraExecutor;
    private boolean isScanning = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan);

        previewView = findViewById(R.id.camera_preview);
        scanLine = findViewById(R.id.scan_line);
        hintText = findViewById(R.id.tv_hint);

        // 初始化相机执行器
        cameraExecutor = Executors.newSingleThreadExecutor();

        // 检查权限并启动相机
        if (hasCameraPermission()) {
            startCamera();
        } else {
            requestCameraPermission();
        }

        // 延迟启动扫描动画，确保视图布局完成
        new Handler().post(this::startScanAnimation);
    }

    private boolean hasCameraPermission() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
    }

    private void requestCameraPermission() {
        ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_CODE_CAMERA_PERMISSION);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_CAMERA_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startCamera();
            } else {
                if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
                    Toast.makeText(this, "请在设置中允许相机权限", Toast.LENGTH_LONG).show();
                    Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    intent.setData(android.net.Uri.parse("package:" + getPackageName()));
                    startActivity(intent);
                }
                finish();
            }
        }
    }

    private void startCamera() {
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                bindCameraUseCases(cameraProvider);
            } catch (ExecutionException | InterruptedException e) {
                Log.e("ScanActivity", "相机启动失败: " + e.getMessage());
            }
        }, ContextCompat.getMainExecutor(this));
    }

    @SuppressLint("UnsafeOptInUsageError")
    private void bindCameraUseCases(@NonNull ProcessCameraProvider cameraProvider) {
        // 预览用例
        Preview preview = new Preview.Builder().build();
        preview.setSurfaceProvider(previewView.getSurfaceProvider());

        // 图像分析用例（二维码扫描）
        ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                .build();

        // ML Kit 二维码扫描配置
        BarcodeScannerOptions options = new BarcodeScannerOptions.Builder()
                .setBarcodeFormats(Barcode.FORMAT_QR_CODE)
                .build();
        BarcodeScanner scanner = BarcodeScanning.getClient(options);

        imageAnalysis.setAnalyzer(cameraExecutor, imageProxy -> {
            try (ImageProxy imageProxyFinal = imageProxy) {
                if (!isScanning || imageProxyFinal.getImage() == null) {
                    return;
                }

                // 转换图像格式
                InputImage inputImage = InputImage.fromMediaImage(
                        imageProxyFinal.getImage(),
                        imageProxyFinal.getImageInfo().getRotationDegrees()
                );

                // 执行扫描
                scanner.process(inputImage)
                        .addOnSuccessListener(barcodes -> handleBarcodeResult(barcodes))
                        .addOnFailureListener(e -> Log.e("ScanActivity", "扫描失败: " + e.getMessage()))
                        .addOnCompleteListener(task -> imageProxyFinal.close());
            } catch (Exception e) {
                Log.e("ScanActivity", "图像分析失败: " + e.getMessage());
            }
        });

        // 选择后置摄像头
        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
                .build();

        // 绑定用例
        try {
            cameraProvider.unbindAll();
            Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis);
        } catch (Exception e) {
            Log.e("ScanActivity", "相机绑定失败: " + e.getMessage());
        }
    }

    private void handleBarcodeResult(List<Barcode> barcodes) {
        runOnUiThread(() -> hintText.setText("正在扫描..."));
        for (Barcode barcode : barcodes) {
            if (barcode.getRawValue() != null) {
                isScanning = false;
                Intent resultIntent = new Intent();
                resultIntent.putExtra("SCAN_RESULT", barcode.getRawValue());
                setResult(Activity.RESULT_OK, resultIntent);

                // 显示成功提示并关闭界面
                runOnUiThread(() -> {
                    hintText.setText("扫描成功！");
                    scanLine.clearAnimation();
                    scanLine.setVisibility(View.GONE);
                });

                new Handler().postDelayed(this::finish, 1000);
                return;
            }
        }
    }

    private void startScanAnimation() {
        previewView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                previewView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                int scanLineHeight = scanLine.getHeight();
                int previewHeight = previewView.getHeight() - scanLineHeight;

                if (previewHeight <= 0) return;

                TranslateAnimation animation = new TranslateAnimation(
                        Animation.ABSOLUTE, 0f,
                        Animation.ABSOLUTE, 0f,
                        Animation.ABSOLUTE, 0f,
                        Animation.ABSOLUTE, previewHeight
                );
                animation.setDuration(2000);
                animation.setRepeatCount(Animation.INFINITE);
                animation.setRepeatMode(Animation.REVERSE);
                scanLine.startAnimation(animation);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (cameraExecutor != null && !cameraExecutor.isShutdown()) {
            cameraExecutor.shutdown();
        }
    }
}